delay = (ms, func) -> setTimeout func, ms

sim = {}

class RuS.SlideInMenu
  
  constructor: (options = {}) ->
    layout = _.extend {}, { padding_left: 100, padding_top: 0, m: 3, n: 3, p: 20 }, (options.layout || {})
    sim = 
      handle: $('#sim-handle')
      container: $('#sim-container')
      overlay: $('#sim-overlay')
      btn: $('.sim-btn')
      isOpen: false
      dest: options.dest
      layout: layout

    sim.handle.show() unless sim.layout.hide_handle
    sim.handle.click toggle.bind(@)
    sim.btn.click click.bind(@)
    $(window).on 'resize', () -> close()
    # handleMove()

    # firefox fix (jQuery.browser.mozilla)
    e.css({ x: 0 }) for e in [sim.handle, sim.overlay, sim.container, sim.btn]

class RuS.TouchSIM extends RuS.SlideInMenu
  constructor: () ->
    super { dest: destPositionTouch }

class RuS.SIM extends RuS.SlideInMenu
  constructor: () ->
    super { dest: destPosition, layout: { width: 300, padding_top: 48, hide_handle: true, btn_height: 50, m: 1, n: 10, p: 3 } }
    $('#sim').addClass('narrow')

toggle = () ->
  if sim.isOpen
    frontend.model.gui.popup(false)
    close()
  else
    frontend.model.gui.popup(true)
    open()

open = () ->
  unless sim.isOpen
    bb = boundingBox()
    sim.overlay.show() unless sim.layout.hide_handle
    sim.handle
      .addClass('active')
      .data({ 'opacity-before': sim.handle.css('opacity') })
      .transition({x: -bb.w, opacity: 0.9}, () -> {})
    sim.container
      .show()
      .data({ 'opacity-before': sim.container.css('opacity') })
      .css({ right: -bb.w, width: bb.w })
      .transition({x: -bb.w, opacity: 0.5}, () -> touchFix())
    $('.sim-btn:not([sim-set])').each (idx) ->
      el = $(this)
      renderIcon el
      el.transition(_.extend(sim.dest.start(el, idx), { opacity: 0.9 }))
    sim.isOpen = true

close = () ->
  if sim.isOpen
    sim.overlay.hide()
    sim.handle
      .removeClass('active')
      .transition({x: 0, opacity: sim.handle.data('opacity-before')}, () -> {})
    sim.container
      .transition({x: 0, opacity: sim.container.data('opacity-before')}, () -> sim.container.hide())
    $('.sim-btn').removeClass('anchored').each (idx) ->
      $(this).transition({ x: 0, y: 0, opacity: 0.9 }, () -> $(this).hide())
    sim.isOpen = false

click = (e) ->
  btn = $(e.target).closest('.sim-btn')
  cmd = btn.attr('sim-data').split(':')[0]
  return unless cmd == 'set' || cmd == 'cmd'

  btn.addClass('active')
  delay 100, ->
    btn.removeClass('active')
    if data = btn.attr('sim-data')
      data = data.split(':')
      switch data[0]
        when 'anchor'
          toggle()
          $('[sim-anchor="' + data[1] + '"]').click()
        when 'url'
          toggle()
          app.navigate(data[1], true)
        when 'cmd'
          btn.trigger(data[1])
        when 'set'
          toggleSet(data[1], btn)

toggleSet = (name, el) ->
  if (el.hasClass('anchored')) 
    $('.sim-btn:not([sim-data="set:N"]):not([sim-set="N"])'.replace(/N/g, name))
      .show()
      .transition({ opacity: 0.9 })
    el.removeClass('anchored')
      .transition(sim.dest.move(el, 0))
    $('.sim-btn[sim-set=N]'.replace(/N/g, name)).each (idx) ->
      $(this).transition({ x: 0, y: 0, opacity: 0.9 }, () -> $(this).hide())
  else 
    $('.sim-btn:not([sim-data="set:N"]):not([sim-set="N"])'.replace(/N/g, name))
      .transition { opacity: 0 }, () -> $(this).hide()
    el.addClass('anchored').transition(sim.dest.move(el, 0))
    $('.sim-btn[sim-set=N]'.replace(/N/g, name)).each (idx) ->
      offset = if sim.layout.m == 1 then 1 else sim.layout.n 
      $(this).transition(_.extend(sim.dest.start($(this), idx + offset), { opacity: 0.9 }), () -> touchFix())
      renderIcon $(this)

boundingBox = () ->
  x1 = $(window).width()
  y1 = $(window).height()
  x = if sim.layout.width then x1 - sim.layout.width else sim.layout.padding_left
  y = sim.layout.padding_top
  { x: x, y: y, x1: x1, y1: y1, w: x1 - x, h: y1 - y, m: sim.layout.m, n: sim.layout.n, p: sim.layout.p }

renderIcon = (el) ->
  if icon = el.attr('sim-icon')
    el.find('i').remove()
    el.prepend("<i class='#{icon}'></i>")
    # el.css('textAlign', 'left').find('div').css(
    #   # 'padding':'0 10px 0 75px',
    #   # 'textAlign': 'left'
    # )
  else if image = el.attr('sim-image')
    el.css(
      'background-image': "url('#{image}')"
      'background-position': '20px center'
      'background-repeat': 'no-repeat'
      'background-size': '50px'
    ).find('div').css(
      'padding': '0 10px 0 80px'
      'text-align': 'left'
    )
  else
    el.css('padding-left', '48px')

destPosition = do () ->
  return {
    start: (el, idx) ->
      # idx = el.attr('sim-pos') || idx

      bb = boundingBox() 
      btn_w = ~~(bb.w / bb.m - bb.p * 2)

      if sim.layout.btn_height
        btn_h = sim.layout.btn_height
        x = ~~(bb.x1 + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - btn_w / 2)
        y = bb.y + ~~(idx % bb.n + 0.5) * btn_h
        s = el.show().css({ width: btn_w, height: btn_h, left: x, top: y }).position()
        { 
          x: ~~(bb.x + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - s.left - el.outerWidth() / 2),
          # y: ~~((idx % bb.n + 0.5) * (bb.h / bb.n) - s.top - el.outerHeight() / 2)
        }
      else
        btn_h = ~~(bb.h / bb.n - bb.p * 2)
        x = ~~(bb.x1 + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - btn_w / 2)
        y = ~~((idx % bb.n + 0.5) * (bb.h / bb.n) - btn_h / 2)
        s = el.show().css({ width: btn_w, height: btn_h, left: x, top: y }).position()
        { 
          x: ~~(bb.x + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - s.left - el.outerWidth() / 2),
          y: ~~((idx % bb.n + 0.5) * (bb.h / bb.n) - s.top - el.outerHeight() / 2)
        }

    move: (el, idx) ->
      bb = boundingBox()
      s = el.position()
      if sim.layout.btn_height
        { 
          x: ~~(-bb.w + bb.x + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - s.left - el.outerWidth() / 2)
          y: bb.y + ~~((idx % bb.n + 0.5) * sim.layout.btn_height - s.top - sim.layout.btn_height / 2)
        }
      else
        { 
          x: ~~(-bb.w + bb.x + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - s.left - el.outerWidth() / 2)
          y: ~~((idx % bb.m + 0.5) * (bb.h / bb.n) - s.top - el.outerHeight() / 2)
        }
  }

destPositionTouch = do () ->
  return {
    start: (el, idx) ->
      idx = el.attr('sim-pos') || idx

      bb = boundingBox()
      btn_w = ~~(bb.w / bb.m - bb.p * 2)
      btn_h = ~~(bb.h / bb.n - bb.p * 2)
      x = ~~(bb.x1 + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - btn_w / 2)
      y = ~~((idx % bb.n + 0.5) * (bb.h / bb.n) - btn_h / 2)
      s = el.show().css({ width: btn_w, height: btn_h, left: x, top: y }).position()

      { 
        x: ~~(bb.x + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - s.left - el.outerWidth() / 2),
        y: ~~((idx % bb.n + 0.5) * (bb.h / bb.n) - s.top - el.outerHeight() / 2)
      }

    move: (el, idx) ->
      bb = boundingBox()
      s = el.position()
      { 
        x: ~~(-bb.w + bb.x + (~~(idx / bb.n) + 0.5) * (bb.w / bb.m) - s.left - el.outerWidth() / 2)
        # y: ~~((idx % m + 0.5) * (h / n) - s.top - el.outerHeight() / 2)
      }
  }

# touch swipe fix
touchFix = () ->
  if $.RusDevice.isAndroid()
    elm = $('.hd-freq-text')
    w = elm.width()
    delay 0, () -> elm.width(w + 1)
    delay 1000, () -> elm.width(w)

